// @TODO Subclass called TimerClock which allows tick event handling.
package org.gof.application.Clock
{
	import com.iMANIT.DS.DubLinkedList.DLLnode;
	import com.iMANIT.DS.DubLinkedList.DubLinkedList;
	import com.iMANIT.OO.ThisIs;
	
	public class BaseClock
	{
		protected var childern:Vector.<BaseClock>;
		protected var lastStatePlaying: Vector.<Boolean>;
		protected var notifies:Boolean;
		
		private var subscriptions:DubLinkedList;
		public var tickCount:int;
		protected var _playing:Boolean;
		
		
		
		public function BaseClock(notifies:Boolean)
		{
			this.notifies = notifies;
			subscriptions = new DubLinkedList();
			childern = new Vector.<BaseClock>();
			lastStatePlaying = new Vector.<Boolean>();
			tickCount = 0;
		}
		
		public function subscribe(func:Function):void
		{
			subscriptions.insertEnding(func);
		}
		
		private function notifyAll():void
		{
			
			var ptr:DLLnode = subscriptions.tail;
			var func:Function;
			do
			{
				func = ptr.payload;
				func.call(null, tickCount);
				ptr = ptr.forward;
			}
			while (ptr)
		}
		
		protected function tick():void
		{
			tickCount++;
			notifyAll();
		}
		public function get ticks():Number
		{
			ThisIs.anAbstractFunction();
			return 1;
		}
		
		
		public function get playing():Boolean
		{
			return _playing;
		}
		public function pause():void
		{
			_playing = false;
			pauseChildern();
		}

		public function play():void
		{
			_playing = true;
			lastStateChildern();
		}
		public function addChild(child:BaseClock):void
		{
			childern.push(child);	
		}
		
		private function pauseChildern():void
		{
			for (var cntx:int = 0; cntx < childern.length; cntx++)
			{
				var child:BaseClock = childern[cntx];
				lastStatePlaying[cntx] = child.playing;
				if (lastStatePlaying[cntx])
				{
					child.pause();
				}
			}	
		}
		
		private function lastStateChildern():void
		{
			for (var cntx:int = 0; cntx < childern.length; cntx++)
			{
				var child:BaseClock = childern[cntx];
				if (lastStatePlaying[cntx])
				{
					child.play();
				}
			}
		} 
		
		
	}
}